using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using ExtendedDotNET.Controls.SimpleLine;

namespace ExtendedDotNET.Controls.SimpleBox
{
	/// <summary>
	/// Summary description for simpleBoxContainer.
	/// </summary>
	[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))] 
	public class SimpleBoxContainer : UserControl
	{
		#region D E C L A R A T I O N S

		private LineStyle _lineStyle ;
		private Color _color = Color.Black ;
		private Color _fillColor = Color.Transparent ;
		private int _lineWidth = 1 ;
		private bool _fitToParent;
		private Color _gradient = Color.Transparent ;
		private bool _useGradient;
		private GradientDirection _gradientAngle = GradientDirection.Horizontal ;
		private Bitmap _backBuffer;

		/// <summary>
		/// Required designer variable.
		/// </summary>
		private readonly Container _components;

		#endregion

		public SimpleBoxContainer(Container components)
		{
		    _components = components;
		    // This call is required by the Windows.Forms Form Designer.
			InitializeComponent();
			//SetStyle( ControlStyles.UserPaint, true ) ;
			SetStyle( ControlStyles.Opaque, true ) ;
			SetStyle( ControlStyles.ResizeRedraw, true ) ;
			Invalidate( true ) ;
		}

		/// <summary> 
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(_components != null)
				{
					_components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region P R O P E R T I E S

		[Category("Custom")]
		public GradientDirection GradientAngle
		{
			get { return _gradientAngle ; }
			set 
			{ 
				_gradientAngle = value ;
				Invalidate( true ) ;
			}
		}

		[Category("Custom")]
		public bool FitToParent
		{
			get { return _fitToParent ; }
			set
			{
				_fitToParent = value ;
				Invalidate( true ) ;
			}
		}

		[Category("Custom")]
		public bool UseGradient
		{
			get { return _useGradient ; }
			set
			{
				_useGradient = value ;
				Invalidate( true );
			}
		}

		[Category("Custom")]
		public Color FillColor
		{
			get { return _fillColor ; }
			set 
			{ 
				_fillColor = value ; 
				Invalidate( true ) ;
			}
		}

		[Category("Custom")]
		public Color Gradient
		{
			get { return _gradient ; }
			set 
			{ 
				_gradient = value ;
				Invalidate( true ) ;
			}
		}

		[Category("Custom")]
		public Color LineColor
		{
			get 
			{ 
				if ( _color == Color.Transparent ) { _color = Parent.BackColor ; }
				return _color ; 
			}
			set 
			{ 
				_color = value ; 
				Invalidate( true ) ;
			}
		}

		[Category("Custom")]
		public int LineWidth
		{
			get { return _lineWidth ; }
			set 
			{ 
				_lineWidth = value ; 
				Invalidate( true ) ;
			}
		}
		[Browsable(false)]
		public LineStyle Style
		{
			get { return _lineStyle ; }
			set 
			{ 
				_lineStyle = LineStyle.Box ;
				if ((value == LineStyle.Box) && ((Width <= LineWidth) || (Height <= LineWidth)))
				{
					Height = 50 ;
					Width = 50 ; 
				}
				Invalidate( true ) ;
			}
		}

		#endregion

		#region M E T H O D S

		protected override void InitLayout()
		{
			base.InitLayout( ) ;
			if ( null == Parent ) return ;
			if ( _fillColor == Color.Transparent ) _fillColor = Parent.BackColor ;
			if ( _lineStyle == LineStyle.None ) 
			{ 
				_lineStyle = LineStyle.Box ; 
				_lineWidth = 1 ;
				Left = (Parent.Width /2)  - Width / 2 ;
				Top = Parent.Height / 2 ;
				Invalidate( true ) ;
			}
		}

		protected override void OnPaintBackground(PaintEventArgs pevent)
		{
			//base.OnPaintBackground (pevent);
		}

		protected override void OnSizeChanged(EventArgs e) 
		{ 
			if(_backBuffer!=null) 
			{ 
				_backBuffer.Dispose(); 
				_backBuffer=null; 
			} 
			base.OnSizeChanged (e); 
		} 


		protected override void OnPaint(PaintEventArgs e)
		{
		    if ( _backBuffer == null || DesignMode  )
			{
				_backBuffer = new Bitmap( ClientSize.Width, ClientSize.Height ) ; 
				Graphics g = Graphics.FromImage( _backBuffer ) ;

				var pn = new Pen( _color, _lineWidth ) ; 
				//Point pt1 = new Point( 0, 0 ); 
				if ( _lineStyle == LineStyle.Box ) 
				{
					Brush br ;
					Rectangle rect = ClientRectangle ;

					if ( _useGradient ) br = new LinearGradientBrush( ClientRectangle, _fillColor, _gradient, ( _gradientAngle == GradientDirection.Horizontal ) ? 0 : 90, false ) ;
					else br = new SolidBrush( _fillColor ) ;

					g.FillRectangle( br, ClientRectangle ) ;
					decimal mod = Decimal.Remainder( _lineWidth, 2 ) ;
					int offset = 0 ;
					if ( (mod != 0) && (_lineWidth != 1) ) offset = 1 ;

					rect.Offset( _lineWidth / 2, _lineWidth / 2 ) ;
					rect.Height = rect.Height - _lineWidth + offset - 1 ;
					rect.Width = rect.Width - _lineWidth + offset - 1 ;
					if ( _lineWidth > 0 ) g.DrawRectangle( pn, rect ) ;
					br.Dispose( ) ;
				}
				g.Dispose( ) ;
			}
			e.Graphics.DrawImageUnscaled( _backBuffer, 0, 0 ) ;
		    foreach ( Control ctl in Controls )
			{
				if ( e.Graphics.ClipBounds.IntersectsWith( ctl.ClientRectangle ) )
				{
					string typeName = ctl.GetType().Name;
					int idx = typeName.IndexOf("TransparentLabel", StringComparison.Ordinal);
					if ( idx >= 0 ) ctl.Invalidate( true ) ;
				}
			}
		}

		#endregion

		#region Component Designer generated code
		/// <summary> 
		/// Required method for Designer support - do not modify 
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			// 
			// simpleBoxContainer
			// 
			this.BackColor = System.Drawing.SystemColors.Control;
			this.Name = "simpleBoxContainer";

		}
		#endregion
	}
}
